#include "UnicodeWidth.h"




UnicodeWidth::Type UnicodeWidth::type(uint32_t c)
{
	static Range widthtype_table[] = {
		0x00000000, 0x0000001f, Type::Neutral,
		0x00000020, 0x0000007e, Type::Narrow,
		0x0000007f, 0x000000a0, Type::Neutral,
		0x000000a1, 0x000000a1, Type::Ambigous,
		0x000000a2, 0x000000a3, Type::Narrow,
		0x000000a4, 0x000000a4, Type::Ambigous,
		0x000000a5, 0x000000a6, Type::Narrow,
		0x000000a7, 0x000000a8, Type::Ambigous,
		0x000000a9, 0x000000a9, Type::Neutral,
		0x000000aa, 0x000000aa, Type::Ambigous,
		0x000000ab, 0x000000ab, Type::Neutral,
		0x000000ac, 0x000000ac, Type::Narrow,
		0x000000ad, 0x000000ae, Type::Ambigous,
		0x000000af, 0x000000af, Type::Narrow,
		0x000000b0, 0x000000b4, Type::Ambigous,
		0x000000b5, 0x000000b5, Type::Neutral,
		0x000000b6, 0x000000ba, Type::Ambigous,
		0x000000bb, 0x000000bb, Type::Neutral,
		0x000000bc, 0x000000bf, Type::Ambigous,
		0x000000c0, 0x000000c5, Type::Neutral,
		0x000000c6, 0x000000c6, Type::Ambigous,
		0x000000c7, 0x000000cf, Type::Neutral,
		0x000000d0, 0x000000d0, Type::Ambigous,
		0x000000d1, 0x000000d6, Type::Neutral,
		0x000000d7, 0x000000d8, Type::Ambigous,
		0x000000d9, 0x000000dd, Type::Neutral,
		0x000000de, 0x000000e1, Type::Ambigous,
		0x000000e2, 0x000000e5, Type::Neutral,
		0x000000e6, 0x000000e6, Type::Ambigous,
		0x000000e7, 0x000000e7, Type::Neutral,
		0x000000e8, 0x000000ea, Type::Ambigous,
		0x000000eb, 0x000000eb, Type::Neutral,
		0x000000ec, 0x000000ed, Type::Ambigous,
		0x000000ee, 0x000000ef, Type::Neutral,
		0x000000f0, 0x000000f0, Type::Ambigous,
		0x000000f1, 0x000000f1, Type::Neutral,
		0x000000f2, 0x000000f3, Type::Ambigous,
		0x000000f4, 0x000000f6, Type::Neutral,
		0x000000f7, 0x000000fa, Type::Ambigous,
		0x000000fb, 0x000000fb, Type::Neutral,
		0x000000fc, 0x000000fc, Type::Ambigous,
		0x000000fd, 0x000000fd, Type::Neutral,
		0x000000fe, 0x000000fe, Type::Ambigous,
		0x000000ff, 0x00000100, Type::Neutral,
		0x00000101, 0x00000101, Type::Ambigous,
		0x00000102, 0x00000110, Type::Neutral,
		0x00000111, 0x00000111, Type::Ambigous,
		0x00000112, 0x00000112, Type::Neutral,
		0x00000113, 0x00000113, Type::Ambigous,
		0x00000114, 0x0000011a, Type::Neutral,
		0x0000011b, 0x0000011b, Type::Ambigous,
		0x0000011c, 0x00000125, Type::Neutral,
		0x00000126, 0x00000127, Type::Ambigous,
		0x00000128, 0x0000012a, Type::Neutral,
		0x0000012b, 0x0000012b, Type::Ambigous,
		0x0000012c, 0x00000130, Type::Neutral,
		0x00000131, 0x00000133, Type::Ambigous,
		0x00000134, 0x00000137, Type::Neutral,
		0x00000138, 0x00000138, Type::Ambigous,
		0x00000139, 0x0000013e, Type::Neutral,
		0x0000013f, 0x00000142, Type::Ambigous,
		0x00000143, 0x00000143, Type::Neutral,
		0x00000144, 0x00000144, Type::Ambigous,
		0x00000145, 0x00000147, Type::Neutral,
		0x00000148, 0x0000014b, Type::Ambigous,
		0x0000014c, 0x0000014c, Type::Neutral,
		0x0000014d, 0x0000014d, Type::Ambigous,
		0x0000014e, 0x00000151, Type::Neutral,
		0x00000152, 0x00000153, Type::Ambigous,
		0x00000154, 0x00000165, Type::Neutral,
		0x00000166, 0x00000167, Type::Ambigous,
		0x00000168, 0x0000016a, Type::Neutral,
		0x0000016b, 0x0000016b, Type::Ambigous,
		0x0000016c, 0x000001cd, Type::Neutral,
		0x000001ce, 0x000001ce, Type::Ambigous,
		0x000001cf, 0x000001cf, Type::Neutral,
		0x000001d0, 0x000001d0, Type::Ambigous,
		0x000001d1, 0x000001d1, Type::Neutral,
		0x000001d2, 0x000001d2, Type::Ambigous,
		0x000001d3, 0x000001d3, Type::Neutral,
		0x000001d4, 0x000001d4, Type::Ambigous,
		0x000001d5, 0x000001d5, Type::Neutral,
		0x000001d6, 0x000001d6, Type::Ambigous,
		0x000001d7, 0x000001d7, Type::Neutral,
		0x000001d8, 0x000001d8, Type::Ambigous,
		0x000001d9, 0x000001d9, Type::Neutral,
		0x000001da, 0x000001da, Type::Ambigous,
		0x000001db, 0x000001db, Type::Neutral,
		0x000001dc, 0x000001dc, Type::Ambigous,
		0x000001dd, 0x00000250, Type::Neutral,
		0x00000251, 0x00000251, Type::Ambigous,
		0x00000252, 0x00000260, Type::Neutral,
		0x00000261, 0x00000261, Type::Ambigous,
		0x00000262, 0x000002c3, Type::Neutral,
		0x000002c4, 0x000002c4, Type::Ambigous,
		0x000002c5, 0x000002c6, Type::Neutral,
		0x000002c7, 0x000002c7, Type::Ambigous,
		0x000002c8, 0x000002c8, Type::Neutral,
		0x000002c9, 0x000002cb, Type::Ambigous,
		0x000002cc, 0x000002cc, Type::Neutral,
		0x000002cd, 0x000002cd, Type::Ambigous,
		0x000002ce, 0x000002cf, Type::Neutral,
		0x000002d0, 0x000002d0, Type::Ambigous,
		0x000002d1, 0x000002d7, Type::Neutral,
		0x000002d8, 0x000002db, Type::Ambigous,
		0x000002dc, 0x000002dc, Type::Neutral,
		0x000002dd, 0x000002dd, Type::Ambigous,
		0x000002de, 0x000002de, Type::Neutral,
		0x000002df, 0x000002df, Type::Ambigous,
		0x000002e0, 0x000002ff, Type::Neutral,
		0x00000300, 0x0000036f, Type::Ambigous,
		0x00000374, 0x00000390, Type::Neutral,
		0x00000391, 0x000003a9, Type::Ambigous,
		0x000003aa, 0x000003b0, Type::Neutral,
		0x000003b1, 0x000003c1, Type::Ambigous,
		0x000003c2, 0x000003c2, Type::Neutral,
		0x000003c3, 0x000003c9, Type::Ambigous,
		0x000003ca, 0x00000400, Type::Neutral,
		0x00000401, 0x00000401, Type::Ambigous,
		0x00000402, 0x0000040f, Type::Neutral,
		0x00000410, 0x0000044f, Type::Ambigous,
		0x00000450, 0x00000450, Type::Neutral,
		0x00000451, 0x00000451, Type::Ambigous,
		0x00000452, 0x000010fc, Type::Neutral,
		0x00001100, 0x0000115f, Type::Wide,
		0x00001160, 0x0000200f, Type::Neutral,
		0x00002010, 0x00002010, Type::Ambigous,
		0x00002011, 0x00002012, Type::Neutral,
		0x00002013, 0x00002016, Type::Ambigous,
		0x00002017, 0x00002017, Type::Neutral,
		0x00002018, 0x00002019, Type::Ambigous,
		0x0000201a, 0x0000201b, Type::Neutral,
		0x0000201c, 0x0000201d, Type::Ambigous,
		0x0000201e, 0x0000201f, Type::Neutral,
		0x00002020, 0x00002022, Type::Ambigous,
		0x00002023, 0x00002023, Type::Neutral,
		0x00002024, 0x00002027, Type::Ambigous,
		0x00002028, 0x0000202f, Type::Neutral,
		0x00002030, 0x00002030, Type::Ambigous,
		0x00002031, 0x00002031, Type::Neutral,
		0x00002032, 0x00002033, Type::Ambigous,
		0x00002034, 0x00002034, Type::Neutral,
		0x00002035, 0x00002035, Type::Ambigous,
		0x00002036, 0x0000203a, Type::Neutral,
		0x0000203b, 0x0000203b, Type::Ambigous,
		0x0000203c, 0x0000203d, Type::Neutral,
		0x0000203e, 0x0000203e, Type::Ambigous,
		0x0000203f, 0x00002071, Type::Neutral,
		0x00002074, 0x00002074, Type::Ambigous,
		0x00002075, 0x0000207e, Type::Neutral,
		0x0000207f, 0x0000207f, Type::Ambigous,
		0x00002080, 0x00002080, Type::Neutral,
		0x00002081, 0x00002084, Type::Ambigous,
		0x00002085, 0x000020a8, Type::Neutral,
		0x000020a9, 0x000020a9, Type::Half,
		0x000020aa, 0x000020ab, Type::Neutral,
		0x000020ac, 0x000020ac, Type::Ambigous,
		0x000020ad, 0x00002102, Type::Neutral,
		0x00002103, 0x00002103, Type::Ambigous,
		0x00002104, 0x00002104, Type::Neutral,
		0x00002105, 0x00002105, Type::Ambigous,
		0x00002106, 0x00002108, Type::Neutral,
		0x00002109, 0x00002109, Type::Ambigous,
		0x0000210a, 0x00002112, Type::Neutral,
		0x00002113, 0x00002113, Type::Ambigous,
		0x00002114, 0x00002115, Type::Neutral,
		0x00002116, 0x00002116, Type::Ambigous,
		0x00002117, 0x00002120, Type::Neutral,
		0x00002121, 0x00002122, Type::Ambigous,
		0x00002123, 0x00002125, Type::Neutral,
		0x00002126, 0x00002126, Type::Ambigous,
		0x00002127, 0x0000212a, Type::Neutral,
		0x0000212b, 0x0000212b, Type::Ambigous,
		0x0000212c, 0x0000214e, Type::Neutral,
		0x00002153, 0x00002154, Type::Ambigous,
		0x00002155, 0x0000215a, Type::Neutral,
		0x0000215b, 0x0000215e, Type::Ambigous,
		0x0000215f, 0x0000215f, Type::Neutral,
		0x00002160, 0x0000216b, Type::Ambigous,
		0x0000216c, 0x0000216f, Type::Neutral,
		0x00002170, 0x00002179, Type::Ambigous,
		0x0000217a, 0x00002184, Type::Neutral,
		0x00002190, 0x00002199, Type::Ambigous,
		0x0000219a, 0x000021b7, Type::Neutral,
		0x000021b8, 0x000021b9, Type::Ambigous,
		0x000021ba, 0x000021d1, Type::Neutral,
		0x000021d2, 0x000021d2, Type::Ambigous,
		0x000021d3, 0x000021d3, Type::Neutral,
		0x000021d4, 0x000021d4, Type::Ambigous,
		0x000021d5, 0x000021e6, Type::Neutral,
		0x000021e7, 0x000021e7, Type::Ambigous,
		0x000021e8, 0x000021ff, Type::Neutral,
		0x00002200, 0x00002200, Type::Ambigous,
		0x00002201, 0x00002201, Type::Neutral,
		0x00002202, 0x00002203, Type::Ambigous,
		0x00002204, 0x00002206, Type::Neutral,
		0x00002207, 0x00002208, Type::Ambigous,
		0x00002209, 0x0000220a, Type::Neutral,
		0x0000220b, 0x0000220b, Type::Ambigous,
		0x0000220c, 0x0000220e, Type::Neutral,
		0x0000220f, 0x0000220f, Type::Ambigous,
		0x00002210, 0x00002210, Type::Neutral,
		0x00002211, 0x00002211, Type::Ambigous,
		0x00002212, 0x00002214, Type::Neutral,
		0x00002215, 0x00002215, Type::Ambigous,
		0x00002216, 0x00002219, Type::Neutral,
		0x0000221a, 0x0000221a, Type::Ambigous,
		0x0000221b, 0x0000221c, Type::Neutral,
		0x0000221d, 0x00002220, Type::Ambigous,
		0x00002221, 0x00002222, Type::Neutral,
		0x00002223, 0x00002223, Type::Ambigous,
		0x00002224, 0x00002224, Type::Neutral,
		0x00002225, 0x00002225, Type::Ambigous,
		0x00002226, 0x00002226, Type::Neutral,
		0x00002227, 0x0000222c, Type::Ambigous,
		0x0000222d, 0x0000222d, Type::Neutral,
		0x0000222e, 0x0000222e, Type::Ambigous,
		0x0000222f, 0x00002233, Type::Neutral,
		0x00002234, 0x00002237, Type::Ambigous,
		0x00002238, 0x0000223b, Type::Neutral,
		0x0000223c, 0x0000223d, Type::Ambigous,
		0x0000223e, 0x00002247, Type::Neutral,
		0x00002248, 0x00002248, Type::Ambigous,
		0x00002249, 0x0000224b, Type::Neutral,
		0x0000224c, 0x0000224c, Type::Ambigous,
		0x0000224d, 0x00002251, Type::Neutral,
		0x00002252, 0x00002252, Type::Ambigous,
		0x00002253, 0x0000225f, Type::Neutral,
		0x00002260, 0x00002261, Type::Ambigous,
		0x00002262, 0x00002263, Type::Neutral,
		0x00002264, 0x00002267, Type::Ambigous,
		0x00002268, 0x00002269, Type::Neutral,
		0x0000226a, 0x0000226b, Type::Ambigous,
		0x0000226c, 0x0000226d, Type::Neutral,
		0x0000226e, 0x0000226f, Type::Ambigous,
		0x00002270, 0x00002281, Type::Neutral,
		0x00002282, 0x00002283, Type::Ambigous,
		0x00002284, 0x00002285, Type::Neutral,
		0x00002286, 0x00002287, Type::Ambigous,
		0x00002288, 0x00002294, Type::Neutral,
		0x00002295, 0x00002295, Type::Ambigous,
		0x00002296, 0x00002298, Type::Neutral,
		0x00002299, 0x00002299, Type::Ambigous,
		0x0000229a, 0x000022a4, Type::Neutral,
		0x000022a5, 0x000022a5, Type::Ambigous,
		0x000022a6, 0x000022be, Type::Neutral,
		0x000022bf, 0x000022bf, Type::Ambigous,
		0x000022c0, 0x00002311, Type::Neutral,
		0x00002312, 0x00002312, Type::Ambigous,
		0x00002313, 0x00002328, Type::Neutral,
		0x00002329, 0x0000232a, Type::Wide,
		0x0000232b, 0x0000244a, Type::Neutral,
		0x00002460, 0x000024e9, Type::Ambigous,
		0x000024ea, 0x000024ea, Type::Neutral,
		0x000024eb, 0x0000254b, Type::Ambigous,
		0x0000254c, 0x0000254f, Type::Neutral,
		0x00002550, 0x00002573, Type::Ambigous,
		0x00002574, 0x0000257f, Type::Neutral,
		0x00002580, 0x0000258f, Type::Ambigous,
		0x00002590, 0x00002591, Type::Neutral,
		0x00002592, 0x00002595, Type::Ambigous,
		0x00002596, 0x0000259f, Type::Neutral,
		0x000025a0, 0x000025a1, Type::Ambigous,
		0x000025a2, 0x000025a2, Type::Neutral,
		0x000025a3, 0x000025a9, Type::Ambigous,
		0x000025aa, 0x000025b1, Type::Neutral,
		0x000025b2, 0x000025b3, Type::Ambigous,
		0x000025b4, 0x000025b5, Type::Neutral,
		0x000025b6, 0x000025b7, Type::Ambigous,
		0x000025b8, 0x000025bb, Type::Neutral,
		0x000025bc, 0x000025bd, Type::Ambigous,
		0x000025be, 0x000025bf, Type::Neutral,
		0x000025c0, 0x000025c1, Type::Ambigous,
		0x000025c2, 0x000025c5, Type::Neutral,
		0x000025c6, 0x000025c8, Type::Ambigous,
		0x000025c9, 0x000025ca, Type::Neutral,
		0x000025cb, 0x000025cb, Type::Ambigous,
		0x000025cc, 0x000025cd, Type::Neutral,
		0x000025ce, 0x000025d1, Type::Ambigous,
		0x000025d2, 0x000025e1, Type::Neutral,
		0x000025e2, 0x000025e5, Type::Ambigous,
		0x000025e6, 0x000025ee, Type::Neutral,
		0x000025ef, 0x000025ef, Type::Ambigous,
		0x000025f0, 0x00002604, Type::Neutral,
		0x00002605, 0x00002606, Type::Ambigous,
		0x00002607, 0x00002608, Type::Neutral,
		0x00002609, 0x00002609, Type::Ambigous,
		0x0000260a, 0x0000260d, Type::Neutral,
		0x0000260e, 0x0000260f, Type::Ambigous,
		0x00002610, 0x00002613, Type::Neutral,
		0x00002614, 0x00002615, Type::Ambigous,
		0x00002616, 0x0000261b, Type::Neutral,
		0x0000261c, 0x0000261c, Type::Ambigous,
		0x0000261d, 0x0000261d, Type::Neutral,
		0x0000261e, 0x0000261e, Type::Ambigous,
		0x0000261f, 0x0000263f, Type::Neutral,
		0x00002640, 0x00002640, Type::Ambigous,
		0x00002641, 0x00002641, Type::Neutral,
		0x00002642, 0x00002642, Type::Ambigous,
		0x00002643, 0x0000265f, Type::Neutral,
		0x00002660, 0x00002661, Type::Ambigous,
		0x00002662, 0x00002662, Type::Neutral,
		0x00002663, 0x00002665, Type::Ambigous,
		0x00002666, 0x00002666, Type::Neutral,
		0x00002667, 0x0000266a, Type::Ambigous,
		0x0000266b, 0x0000266b, Type::Neutral,
		0x0000266c, 0x0000266d, Type::Ambigous,
		0x0000266e, 0x0000266e, Type::Neutral,
		0x0000266f, 0x0000266f, Type::Ambigous,
		0x00002670, 0x0000273c, Type::Neutral,
		0x0000273d, 0x0000273d, Type::Ambigous,
		0x0000273e, 0x00002775, Type::Neutral,
		0x00002776, 0x0000277f, Type::Ambigous,
		0x00002780, 0x000027e5, Type::Neutral,
		0x000027e6, 0x000027eb, Type::Narrow,
		0x000027f0, 0x00002984, Type::Neutral,
		0x00002985, 0x00002986, Type::Narrow,
		0x00002987, 0x00002e1d, Type::Neutral,
		0x00002e80, 0x00002ffb, Type::Wide,
		0x00003000, 0x00003000, Type::Full,
		0x00003001, 0x0000303e, Type::Wide,
		0x0000303f, 0x0000303f, Type::Neutral,
		0x00003041, 0x000033ff, Type::Wide,
		0x00003400, 0x00004db5, Type::Wide,
		0x00004dc0, 0x00004dff, Type::Neutral,
		0x00004e00, 0x00009fbb, Type::Wide,
		0x0000a000, 0x0000a4c6, Type::Wide,
		0x0000a700, 0x0000a877, Type::Neutral,
		0x0000ac00, 0x0000d7a3, Type::Wide,
		0x0000d800, 0x0000db7f, Type::Neutral,
		0x0000db80, 0x0000dbff, Type::Neutral,
		0x0000dc00, 0x0000dfff, Type::Neutral,
		0x0000e000, 0x0000f8ff, Type::Ambigous,
		0x0000f900, 0x0000fad9, Type::Wide,
		0x0000fb00, 0x0000fdfd, Type::Neutral,
		0x0000fe00, 0x0000fe0f, Type::Ambigous,
		0x0000fe10, 0x0000fe19, Type::Wide,
		0x0000fe20, 0x0000fe23, Type::Neutral,
		0x0000fe30, 0x0000fe6b, Type::Wide,
		0x0000fe70, 0x0000feff, Type::Neutral,
		0x0000ff01, 0x0000ff60, Type::Full,
		0x0000ff61, 0x0000ffdc, Type::Half,
		0x0000ffe0, 0x0000ffe6, Type::Full,
		0x0000ffe8, 0x0000ffee, Type::Half,
		0x0000fff9, 0x0000fffc, Type::Neutral,
		0x0000fffd, 0x0000fffd, Type::Ambigous,
		0x00010000, 0x0001d7ff, Type::Neutral,
		0x00020000, 0x0002a6d6, Type::Wide,
		0x0002a6d7, 0x0002f7ff, Type::Wide,
		0x0002f800, 0x0002fa1d, Type::Wide,
		0x0002fa1e, 0x0002fffd, Type::Wide,
		0x00030000, 0x0003fffd, Type::Wide,
		0x000e0001, 0x000e007f, Type::Neutral,
		0x000e0100, 0x000e01ef, Type::Ambigous,
		0x000f0000, 0x000ffffd, Type::Ambigous,
		0x00100000, 0x0010fffd, Type::Ambigous,
	};
	const int widthtype_count = sizeof(widthtype_table) / sizeof(*widthtype_table);

	int lo = 0;
	int hi = widthtype_count;
	while (lo < hi) {
		int mid = (lo + hi) / 2;
		if (c < widthtype_table[mid].lo) {
			hi = mid;
		} else if (c > widthtype_table[mid].hi) {
			lo = mid + 1;
		} else {
			if (c >= widthtype_table[mid].lo && c <= widthtype_table[mid].hi) {
				return widthtype_table[mid].type;
			}
			break;
		}
	}
	return Type::Unknown;
}


